home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 676-700 / 681 / term / source.lha / termMain.c < prev    next >
C/C++ Source or Header  |  1992-05-09  |  62KB  |  2,972 lines

  1. /*
  2. **    $Id: termMain.c,v 1.10 92/05/09 15:54:42 olsen Sta Locker: olsen $
  3. **    $Revision: 1.10 $
  4. **    $Date: 92/05/09 15:54:42 $
  5. **
  6. **    Program main routines and event loop
  7. **
  8. **    Copyright © 1990-1992 by Olaf `Olsen' Barthel & MXM
  9. **        All Rights Reserved
  10. */
  11.  
  12. #include "termGlobal.h"
  13.  
  14.     /* Argument vectors offsets. */
  15.  
  16. enum    {    ARG_KEEPIO,ARG_DONTPOP,ARG_SETTINGS,ARG_COUNT };
  17.  
  18.     /* Argument template. */
  19.  
  20. #define ARGTEMPLATE "K=KEEPIO/S,D=DONTPOP/S,S=SETTINGS/K"
  21.  
  22.     /* Some global variables for starters. */
  23.  
  24. STATIC BYTE    Terminated    = FALSE,
  25.         DoIconify    = FALSE;
  26.  
  27.     /* Local config path variable. */
  28.  
  29. STATIC STRPTR    ConfigPath;
  30. STATIC UBYTE    ThePath[256];
  31.  
  32.     /* main():
  33.      *
  34.      *    This is our main entry point, check for the right
  35.      *    Kickstart version and fire off the background task
  36.      *    if approritate.
  37.      */
  38.  
  39. LONG __saveds
  40. main()
  41. {
  42.     UBYTE *Result;
  43.  
  44.         /* Set up SysBase. */
  45.  
  46.     SysBase = *(struct ExecBase **)4;
  47.  
  48.         /* Are we running as a child of Workbench? */
  49.  
  50.     ThisProcess = (struct Process *)SysBase -> ThisTask;
  51.  
  52.     if(!ThisProcess -> pr_CLI)
  53.     {
  54.         WaitPort(&ThisProcess -> pr_MsgPort);
  55.  
  56.         WBenchMsg = (struct WBStartup *)GetMsg(&ThisProcess -> pr_MsgPort);
  57.     }
  58.     else
  59.         WBenchMsg = NULL;
  60.  
  61.         /* Kickstart 2.0 or higher required, do you hear me? */
  62.  
  63.     if(SysBase -> LibNode . lib_Version < 36)
  64.     {
  65.         if(ThisProcess -> pr_CLI)
  66.         {
  67.             if(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",0))
  68.             {
  69.                 Write(ThisProcess -> pr_COS,"Kickstart 2.0 or higher required.\a\n",35);
  70.  
  71.                 ThisProcess -> pr_Result2 = ERROR_INVALID_RESIDENT_LIBRARY;
  72.  
  73.                 CloseLibrary(DOSBase);
  74.             }
  75.         }
  76.         else
  77.         {
  78.             if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0))
  79.             {
  80.                 STATIC struct IntuiText BodyText =  {0,1,JAM1,5,3,&DefaultFont,(UBYTE *)"Kickstart 2.0 or higher required.", NULL};
  81.                 STATIC struct IntuiText SorryText = {0,1,JAM1,6,3,&DefaultFont,(UBYTE *)"Sorry",NULL};
  82.  
  83.                 struct Window *Window;
  84.  
  85.                 if(Window = (struct Window *)BuildSysRequest(NULL,&BodyText,NULL,&SorryText,GADGETUP,301,46))
  86.                 {
  87.                     struct IntuiMessage *Message;
  88.  
  89.                     ScreenToFront(Window -> WScreen);
  90.  
  91.                     DisplayBeep(Window -> WScreen);
  92.  
  93.                     WaitPort(Window -> UserPort);
  94.  
  95.                     if(Message = (struct IntuiMessage *)GetMsg(Window -> UserPort))
  96.                         ReplyMsg(Message);
  97.  
  98.                     FreeSysRequest(Window);
  99.                 }
  100.  
  101.                 CloseLibrary(IntuitionBase);
  102.             }
  103.         }
  104.  
  105.         if(WBenchMsg)
  106.         {
  107.             Forbid();
  108.  
  109.             ReplyMsg((struct Message *)WBenchMsg);
  110.         }
  111.  
  112.         return(RETURN_FAIL);
  113.     }
  114.  
  115.         /* Now try to open dos.library and go on examining
  116.          * our calling parameters.
  117.          */
  118.  
  119.     if(!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",36)))
  120.     {
  121.         CloseAll();
  122.  
  123.         return(RETURN_FAIL);
  124.     }
  125.  
  126.         /* We were called from Shell. */
  127.  
  128.     if(ThisProcess -> pr_CLI)
  129.     {
  130.         UBYTE **ArgArray;
  131.  
  132.             /* Use the cute ReadArgs parser, allocate the
  133.              * argument vectors...
  134.              */
  135.  
  136.         if(ArgArray = (UBYTE **)AllocVec(sizeof(UBYTE *) * (ARG_COUNT),MEMF_ANY|MEMF_CLEAR))
  137.         {
  138.             struct RDArgs *ArgsPtr;
  139.  
  140.             if(ArgsPtr = (struct RDArgs *)AllocDosObject(DOS_RDARGS,TAG_DONE))
  141.             {
  142.                 ArgsPtr -> RDA_ExtHelp = "\nUsage: \33[1mterm\33[0m [KeepIO] [DontPop] [Settings <Path name>]\n\n         KeepIO = Keep links to the current Shell window.\n        DontPop = Do not pop an already running `term' to the front.\n       Settings = Path to search for settings files.\n\n";
  143.  
  144.                     /* Parse the args (if any). */
  145.  
  146.                 if(ReadArgs(ARGTEMPLATE,(LONG *)ArgArray,ArgsPtr))
  147.                 {
  148.                         /* Pop a running `term' to the front? */
  149.  
  150.                     if((TermPort = (struct TermPort *)FindPort("term Port")) && !ArgArray[ARG_DONTPOP])
  151.                     {
  152.                         if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0))
  153.                         {
  154.                             if(TermPort -> TopWindow)
  155.                                 BumpWindow(TermPort -> TopWindow);
  156.  
  157.                             CloseLibrary(IntuitionBase);
  158.                         }
  159.  
  160.                         FreeArgs(ArgsPtr);
  161.                         FreeDosObject(DOS_RDARGS,ArgsPtr);
  162.                         FreeVec(ArgArray);
  163.  
  164.                         CloseLibrary(DOSBase);
  165.  
  166.                         return(RETURN_OK);
  167.                     }
  168.  
  169.                         /* Are we to use a special settings path? */
  170.  
  171.                     if(ArgArray[ARG_SETTINGS])
  172.                     {
  173.                         ConfigPath = ThePath;
  174.  
  175.                         strcpy(ThePath,ArgArray[ARG_SETTINGS]);
  176.                     }
  177.  
  178.                         /* We are to keep our links to
  179.                          * the Shell.
  180.                          */
  181.  
  182.                     if(ArgArray[ARG_KEEPIO])
  183.                     {
  184.                         BYTE OldPri = ThisProcess -> pr_Task . tc_Node . ln_Pri;
  185.  
  186.                             /* Do we have enough stack space available? */
  187.  
  188.                         if(((struct CommandLineInterface *)BADDR(ThisProcess -> pr_CLI)) -> cli_DefaultStack < 4096)
  189.                         {
  190.                             Printf("\33[1mterm:\33[0m %s.\a\n","Sorry, the Shell stack must be at least 16384 bytes large");
  191.  
  192.                             FreeArgs(ArgsPtr);
  193.                             FreeDosObject(DOS_RDARGS,ArgsPtr);
  194.                             FreeVec(ArgArray);
  195.  
  196.                             CloseLibrary(DOSBase);
  197.  
  198.                             return(RETURN_FAIL);
  199.                         }
  200.  
  201.                             /* Open our resources and
  202.                              * squeak on failure.
  203.                              */
  204.  
  205.                         if(Result = OpenAll(ConfigPath))
  206.                         {
  207.                             if(Result[0])
  208.                                 Printf("\33[1mterm:\33[0m %s!\a\n",Result);
  209.  
  210.                             CloseAll();
  211.  
  212.                             FreeArgs(ArgsPtr);
  213.                             FreeDosObject(DOS_RDARGS,ArgsPtr);
  214.                             FreeVec(ArgArray);
  215.  
  216.                             CloseLibrary(DOSBase);
  217.  
  218.                             return(RETURN_FAIL);
  219.                         }
  220.  
  221.                             /* Go into main input
  222.                              * loop.
  223.                              */
  224.  
  225.                         HandleInput();
  226.  
  227.                             /* Does anybody understand
  228.                              * this joke?
  229.                              */
  230.  
  231.                         Printf("You quit with 0 gold pieces\nTo play again, just type \"term\"\n");
  232.  
  233.                             /* Free the argument
  234.                              * data.
  235.                              */
  236.  
  237.                         FreeArgs(ArgsPtr);
  238.                         FreeDosObject(DOS_RDARGS,ArgsPtr);
  239.                         FreeVec(ArgArray);
  240.  
  241.                             /* Restore old priority. */
  242.  
  243.                         SetTaskPri(ThisProcess,(LONG)OldPri);
  244.  
  245.                             /* Terminate execution. */
  246.  
  247.                         CloseAll();
  248.  
  249.                         CloseLibrary(DOSBase);
  250.  
  251.                         return(RETURN_OK);
  252.                     }
  253.  
  254.                     FreeArgs(ArgsPtr);
  255.                 }
  256.                 else
  257.                 {
  258.                     PrintFault(IoErr(),"term");
  259.  
  260.                     FreeDosObject(DOS_RDARGS,ArgsPtr);
  261.                     FreeVec(ArgArray);
  262.  
  263.                     CloseLibrary(DOSBase);
  264.  
  265.                     return(RETURN_ERROR);
  266.                 }
  267.  
  268.                 FreeDosObject(DOS_RDARGS,ArgsPtr);
  269.             }
  270.  
  271.             FreeVec(ArgArray);
  272.  
  273.                 /* Create a new process from our code. */
  274.  
  275.             if(!SegmentSplit("term main process",0,16384,HandleInput))
  276.             {
  277.                 Printf("\33[1mterm:\33[0m Failed to create new process!\a\n");
  278.  
  279.                 CloseAll();
  280.  
  281.                 CloseLibrary(DOSBase);
  282.  
  283.                 return(RETURN_FAIL);
  284.             }
  285.         }
  286.         else
  287.         {
  288.             Printf("\33[1mterm:\33[0m Failed to allocate argument vectors!\a\n");
  289.  
  290.             CloseLibrary(DOSBase);
  291.  
  292.             return(RETURN_FAIL);
  293.         }
  294.     }
  295.     else
  296.     {
  297.         LONG StackSize;
  298.  
  299.         StackSize = (LONG)SysBase -> ThisTask -> tc_SPUpper - (LONG)SysBase -> ThisTask -> tc_SPLower;
  300.  
  301.         if(StackSize < 16384)
  302.         {
  303.             if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37))
  304.             {
  305.                 MyEasyRequest(NULL,"`term' has a problem:\nThe current stack size of %ld bytes is too low,\nplease edit the icon file to use at least\n16384 bytes and restart the proram.","Continue",StackSize);
  306.  
  307.                 CloseLibrary(IntuitionBase);
  308.             }
  309.  
  310.             if(DOSBase)
  311.                 CloseLibrary(DOSBase);
  312.  
  313.             Forbid();
  314.  
  315.             ReplyMsg((struct Message *)WBenchMsg);
  316.  
  317.             return(RETURN_FAIL);
  318.         }
  319.         else
  320.         {
  321.             CurrentDir(WBenchMsg -> sm_ArgList -> wa_Lock);
  322.  
  323.                 /* Open icon.library, we want to take a
  324.                  * look at the icon.
  325.                  */
  326.  
  327.             if(IconBase = OpenLibrary("icon.library",0))
  328.             {
  329.                 struct DiskObject *Icon;
  330.  
  331.                     /* Try to read the icon file. */
  332.  
  333.                 if(Icon = GetDiskObject(WBenchMsg -> sm_ArgList -> wa_Name))
  334.                 {
  335.                         /* Look for a `Settings' tooltype. */
  336.  
  337.                     if(ConfigPath = FindToolType(Icon -> do_ToolTypes,"SETTINGS"))
  338.                     {
  339.                             /* Remember the path and continue. */
  340.  
  341.                         strcpy(ThePath,ConfigPath);
  342.  
  343.                         ConfigPath = ThePath;
  344.                     }
  345.  
  346.                         /* Free the icon. */
  347.  
  348.                     FreeDiskObject(Icon);
  349.                 }
  350.  
  351.                     /* Close the library. */
  352.  
  353.                 CloseLibrary(IconBase);
  354.  
  355.                 IconBase = NULL;
  356.             }
  357.  
  358.                 /* Initialize this, so OpenAll will work with
  359.                  * correct data.
  360.                  */
  361.  
  362.             TermPort = (struct TermPort *)FindPort("term Port");
  363.  
  364.                 /* We were called from Workbench. */
  365.  
  366.             if(Result = OpenAll(ConfigPath))
  367.             {
  368.                 if(IntuitionBase && Result[0])
  369.                     MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Result);
  370.  
  371.                 CloseAll();
  372.             }
  373.             else
  374.                 HandleInput();
  375.         }
  376.     }
  377.  
  378.     return(RETURN_OK);
  379. }
  380.  
  381.     /* HandleInput():
  382.      *
  383.      *    This is our main input loop (check window & serial).
  384.      */
  385.  
  386. VOID __saveds
  387. HandleInput()
  388. {
  389.     ULONG SignalSet = NULL,SavageSignals = NULL;
  390.  
  391.     ThisProcess = (struct Process *)SysBase -> ThisTask;
  392.  
  393.         /* Open the resources we need. */
  394.  
  395.     if(!IntuitionBase)
  396.     {
  397.         UBYTE *Result;
  398.  
  399.         if(Result = OpenAll(ConfigPath))
  400.         {
  401.             if(IntuitionBase && Result[0])
  402.                 MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Result);
  403.  
  404.             CloseAll();
  405.  
  406.             return;
  407.         }
  408.     }
  409.  
  410.     BumpWindow(Window);
  411.  
  412.         /* Set up the public screen data. */
  413.  
  414.     PubScreenStuff();
  415.  
  416.         /* Change program priority. */
  417.  
  418.     SetTaskPri(ThisProcess,(LONG)Config . Priority);
  419.  
  420.     BlockWindows();
  421.  
  422.         /* Load the phone book. */
  423.  
  424.     LoadPhonebook(LastPhone);
  425.  
  426.         /* Show our business card. */
  427.  
  428.     if(ShowInfo(TRUE))
  429.         SignalSet |= SIG_REXX;
  430.  
  431. /*    MyEasyRequest(Window,"This is a beta-test release of `term' which is\nnot yet ready for release.\n\nTHIS COPY IS NOT FOR DISTRIBUTION!\n\nDies ist eine beta-Testversion von `term',\ndie noch nicht Veröffentlichungsfähig ist.\n\nDIESE KOPIE IST NICHT ZUR VERTEILUNG BESTIMMT!","Continue");*/
  432.  
  433.     ReleaseWindows();
  434.  
  435.         /* Initialize the modem. */
  436.  
  437.     SerialCommand(Config . ModemInit);
  438.  
  439.         /* Execute the startup macro (if any). */
  440.  
  441.     if(Config . StartupMacro[0])
  442.         SerialCommand(Config . StartupMacro);
  443.  
  444.     LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_PROGRAM_STARTED_TXT),TermName,TermDate);
  445.  
  446.         /* Go into input loop... */
  447.  
  448. Loop:    while(!Terminated)
  449.     {
  450.             /* If no longer online, get back to the
  451.              * previous configuration.
  452.              */
  453.  
  454.         if(!Online)
  455.             ChosenEntry = NULL;
  456.  
  457.         if(!Online && CurrentPay)
  458.         {
  459.                 /* Previous configuration available? */
  460.  
  461.             if(BackupConfig)
  462.             {
  463.                     /* Remember old configuration. */
  464.  
  465.                 PrivateConfig = Config;
  466.  
  467.                     /* Copy configuration. */
  468.  
  469.                 memcpy(&Config,BackupConfig,sizeof(struct Configuration));
  470.  
  471.                     /* Set up new configuration. */
  472.  
  473.                 ConfigSetup();
  474.  
  475.                     /* Free old configuration. */
  476.  
  477.                 FreeVec(BackupConfig);
  478.  
  479.                 BackupConfig = NULL;
  480.             }
  481.             else
  482.             {
  483.                 /* Display how much we expect
  484.                  * the user will have to pay for
  485.                  * this call.
  486.                  */
  487.  
  488.                 ConWrites(LocaleString(MSG_TERMMAIN_THIS_CALL_WILL_COST_YOU_TXT),CreateSum(CurrentPay,TRUE));
  489.  
  490.                 CurrentPay = 0;
  491.             }
  492.         }
  493.  
  494.             /* Take care of external terminal emulation library. */
  495.  
  496.         if(SignalSet & XEM_Signal)
  497.         {
  498.             if(!XEmulatorSignal(XEM_IO,SignalSet))
  499.             {
  500.                 CloseEmulator();
  501.  
  502.                 Config . Emulation = EMULATION_ANSIVT100;
  503.  
  504.                 if(Config . Font == FONT_IBM && IBM)
  505.                     CurrentFont = IBM;
  506.                 else
  507.                     CurrentFont = Topaz;
  508.  
  509.                 SetFont(RPort,CurrentFont);
  510.             }
  511.         }
  512.  
  513.             /* A SIG_CLIP will cause us to transmit the current contents of
  514.              * the clipboard...
  515.              */
  516.  
  517.         if(SignalSet & SIG_CLIP)
  518.         {
  519.             LONG Size;
  520.  
  521.             if(Size = LoadClip(SharedBuffer,256))
  522.             {
  523.                 SerWrite(SharedBuffer,Size);
  524.  
  525.                 switch(Config . SendCR)
  526.                 {
  527.                     case CR_IGNORE:    break;
  528.  
  529.                     case CR_ASCR:    SerWrite("\r",1);
  530.                             break;
  531.  
  532.                     case CR_ASCRLF:    SerWrite("\r\n",2);
  533.                             break;
  534.                 }
  535.             }
  536.         }
  537.  
  538.             /* Loop & check until the dust has settled. */
  539.  
  540.         if(SignalSet & (SIG_WINDOW | SavageSignals))
  541.             while(HandleWindow() || HandleSerial() || HandlePacket() || HandleReview());
  542.  
  543.             /* Remove audio request. */
  544.  
  545.         if(SignalSet & SIG_AUDIO)
  546.             ClearAudio();
  547.  
  548.             /* Check if we are to prompt the user for
  549.              * ZModem upload type.
  550.              */
  551.  
  552.         if(UsesZModem)
  553.         {
  554.             if(FlowInfo . ZModemUpload && XProtocolBase)
  555.             {
  556.                 FlowInit();
  557.  
  558.                 if(Config . AutoUpload)
  559.                 {
  560.                     BlockWindows();
  561.  
  562.                     switch(UploadPanel())
  563.                     {
  564.                         case UPLOAD_TEXT:    BinaryTransfer = FALSE;
  565.  
  566.                                     if(!StartXprSend(TRANSFER_TEXT))
  567.                                         SerWrite(ZModemCancel,20);
  568.  
  569.                                     break;
  570.  
  571.                         case UPLOAD_BINARY:    BinaryTransfer = TRUE;
  572.  
  573.                                     if(!StartXprSend(TRANSFER_BINARY))
  574.                                         SerWrite(ZModemCancel,20);
  575.  
  576.                                     break;
  577.  
  578.                         case UPLOAD_IGNORE:    break;
  579.  
  580.                         case UPLOAD_ABORT:    SerWrite(ZModemCancel,20);
  581.                                     break;
  582.                     }
  583.  
  584.                     ReleaseWindows();
  585.                 }
  586.             }
  587.         }
  588.  
  589.             /* Make the user notice not too obvious events. */
  590.  
  591.         if(FlowInfo . Changed && (FlowInfo . Voice || FlowInfo . Ring || FlowInfo . Connect))
  592.         {
  593.             if(!Online)
  594.             {
  595.                 WakeUp(Window,FALSE);
  596.  
  597.                 if(FlowInfo . Voice)
  598.                 {
  599.                     ConWrites(LocaleString(MSG_TERMMAIN_INCOMING_VOIC_CALL_TXT));
  600.  
  601.                     Say(LocaleString(MSG_TERMMAIN_SAY_INCOMING_VOICE_CALL_TXT));
  602.                 }
  603.  
  604.                 if(FlowInfo . Ring)
  605.                 {
  606.                     ConWrites(LocaleString(MSG_TERMMAIN_INCOMING_CALL_TXT));
  607.  
  608.                     Say(LocaleString(MSG_GLOBAL_INCOMING_CALL_TXT));
  609.                 }
  610.  
  611.                 if(FlowInfo . Connect)
  612.                 {
  613.                     Online        = TRUE;
  614.                     BaudPending    = FALSE;
  615.                 }
  616.             }
  617.  
  618.             FlowInit();
  619.         }
  620.  
  621.             /* Check for rexx messages to be processed. */
  622.  
  623.         if(SignalSet & SIG_REXX)
  624.             HandleRexx();
  625.  
  626.             /* Iconify the program? */
  627.  
  628.         if(DoIconify)
  629.         {
  630.             BYTE Released = FALSE;
  631.  
  632.                 /* Set the wait mouse pointer... */
  633.  
  634.             BlockWindows();
  635.  
  636.                 /* Open workbench.library. */
  637.  
  638.             if(WorkbenchBase = OpenLibrary("workbench.library",0))
  639.             {
  640.                     /* Open icon.library. */
  641.  
  642.                 if(IconBase = OpenLibrary("icon.library",0))
  643.                 {
  644.                     struct DiskObject *Icon = NULL;
  645.  
  646.                         /* Get the program icon. */
  647.  
  648.                     if(WBenchMsg)
  649.                     {
  650.                         if(WBenchMsg -> sm_ArgList)
  651.                         {
  652.                             if(WBenchMsg -> sm_ArgList -> wa_Name)
  653.                                 Icon = GetDiskObjectNew(WBenchMsg -> sm_ArgList -> wa_Name);
  654.                         }
  655.                     }
  656.  
  657.                         /* No icon? Use the default name. */
  658.  
  659.                     if(!Icon)
  660.                         Icon = GetDiskObjectNew("term");
  661.  
  662.                         /* Did we get any icon? */
  663.  
  664.                     if(Icon)
  665.                     {
  666.                             /* Not a tool icon? */
  667.  
  668.                         if(Icon -> do_Type != WBTOOL)
  669.                         {
  670.                                 /* Get rid of it... */
  671.  
  672.                             FreeDiskObject(Icon);
  673.  
  674.                                 /* Get the default tool icon. */
  675.  
  676.                             Icon = GetDefDiskObject(WBTOOL);
  677.                         }
  678.                     }
  679.  
  680.                         /* Did we get an icon? */
  681.  
  682.                     if(Icon)
  683.                     {
  684.                         struct MsgPort *IconPort;
  685.  
  686.                             /* Default icon position. */
  687.  
  688.                         Icon -> do_CurrentX = NO_ICON_POSITION;
  689.                         Icon -> do_CurrentY = NO_ICON_POSITION;
  690.  
  691.                             /* Create the Workbench reply port. */
  692.  
  693.                         if(IconPort = CreateMsgPort())
  694.                         {
  695.                             struct AppIcon *AppIcon;
  696.  
  697.                                 /* Add the application icon. */
  698.  
  699.                             if(AppIcon = AddAppIcon(0,0,TermIDString,IconPort,NULL,Icon,NULL))
  700.                             {
  701.                                 BYTE             IconTerminated = FALSE;
  702.                                 struct AppMessage    *AppMessage;
  703.                                 BYTE             HadBuffer = BufferProcess ? TRUE : FALSE;
  704.                                 UBYTE            *String,*Error;
  705.  
  706.                                     /* Release the window. */
  707.  
  708.                                 Released = TRUE;
  709.  
  710.                                 ReleaseWindows();
  711.  
  712.                                     /* Remove the display buffer. */
  713.  
  714.                                 if(BufferProcess)
  715.                                     Signal(BufferProcess,SIGBREAKF_CTRL_C);
  716.  
  717.                                     /* Reset and release the serial driver. */
  718.  
  719.                                 ClearSerial();
  720.  
  721.                                 DeleteSerial();
  722.  
  723.                                     /* Close the display. full stop. */
  724.  
  725.                                 DeleteDisplay();
  726.  
  727.                                     /* Wait for double-click. */
  728.  
  729. IconLoop:                            while(!IconTerminated)
  730.                                 {
  731.                                     ULONG SignalSet = Wait((1 << IconPort -> mp_SigBit) | SIG_REXX);
  732.  
  733.                                     if(SignalSet & (1 << IconPort -> mp_SigBit))
  734.                                     {
  735.                                             /* Pick up application messages. */
  736.  
  737.                                         while(AppMessage = (struct AppMessage *)GetMsg(IconPort))
  738.                                         {
  739.                                                 /* Received a double-click? */
  740.  
  741.                                             IconTerminated = TRUE;
  742.  
  743.                                             ReplyMsg(AppMessage);
  744.                                         }
  745.                                     }
  746.  
  747.                                         /* Wake up if ARexx command received. */
  748.  
  749.                                     if(SignalSet & SIG_REXX)
  750.                                         IconTerminated = TRUE;
  751.                                 }
  752.  
  753.                                     /* The buffer process was running before we
  754.                                      * went into iconified state, so let's try to
  755.                                      * conjure it up again.
  756.                                      */
  757.  
  758.                                 if(HadBuffer)
  759.                                 {
  760.                                     if(BufferProcess = (struct Process *)CreateNewProcTags(
  761.                                         NP_Entry,    BufferServer,
  762.                                         NP_Name,    "term buffer process",
  763.                                         NP_Priority,    0,
  764.                                         NP_StackSize,    8192,
  765.                                         NP_WindowPtr,    -1,
  766.                                     TAG_END))
  767.                                         Wait(SIGBREAKF_CTRL_C);
  768.                                 }
  769.  
  770.                                     /* Open the serial driver. */
  771.  
  772.                                 if(Error = CreateSerial())
  773.                                 {
  774.                                     DeleteSerial();
  775.  
  776.                                     switch(MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_ICONIFY_IGNORE_QUIT_TXT),Error))
  777.                                     {
  778.                                         case 1:        goto IconLoop;
  779.                                         case 2:        break;
  780.                                         case 0:        Terminated = TRUE;
  781.                                     }
  782.                                 }
  783.                                 else
  784.                                 {
  785.                                     if(SerialMessage)
  786.                                     {
  787.                                         MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SerialMessage);
  788.  
  789.                                         SerialMessage = NULL;
  790.                                     }
  791.                                 }
  792.  
  793.                                     /* Create the display. */
  794.  
  795.                                 if(String = CreateDisplay(FALSE))
  796.                                 {
  797.                                     if(MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_ICONIFY_QUIT_TXT),String))
  798.                                     {
  799.                                         ClearSerial();
  800.  
  801.                                         DeleteSerial();
  802.  
  803.                                         IconTerminated = FALSE;
  804.  
  805.                                         goto IconLoop;
  806.                                     }
  807.                                     else
  808.                                         Terminated = FALSE;
  809.                                 }
  810.                                 else
  811.                                 {
  812.                                     BumpWindow(Window);
  813.  
  814.                                     PubScreenStuff();
  815.                                 }
  816.  
  817.                                     /* Remove the application icon. */
  818.  
  819.                                 RemoveAppIcon(AppIcon);
  820.  
  821.                                     /* Reply pending messages. */
  822.  
  823.                                 while(AppMessage = (struct AppMessage *)GetMsg(IconPort))
  824.                                     ReplyMsg(AppMessage);
  825.                             }
  826.                             else
  827.                                 MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_ADD_APPLICATION_ICON_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  828.  
  829.                             DeleteMsgPort(IconPort);
  830.                         }
  831.                         else
  832.                             MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_CREATE_MSGPORT_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  833.  
  834.                         FreeDiskObject(Icon);
  835.                     }
  836.                     else
  837.                         MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_TOOL_ICON_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  838.  
  839.                     CloseLibrary(IconBase);
  840.                 }
  841.                 else
  842.                     MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_ICON_LIBRARY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  843.  
  844.                 CloseLibrary(WorkbenchBase);
  845.             }
  846.             else
  847.                 MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_WORKBENCH_LIBRARY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  848.  
  849.             if(!Released)
  850.                 ReleaseWindows();
  851.  
  852.                 /* Finished! */
  853.  
  854.             DoIconify = FALSE;
  855.  
  856.                 /* Just a check for safety. */
  857.  
  858.             HandleRexx();
  859.         }
  860.  
  861.             /* Reset the serial driver? */
  862.  
  863.         if(ResetSerial)
  864.         {
  865.             UBYTE *Error;
  866.  
  867.             ClearSerial();
  868.  
  869.             DeleteSerial();
  870.  
  871.             BlockWindows();
  872.  
  873. OpenLoop:        if(Error = CreateSerial())
  874.             {
  875.                 APTR OldPtr = ThisProcess -> pr_WindowPtr;
  876.  
  877.                 DeleteSerial();
  878.  
  879.                 ThisProcess -> pr_WindowPtr = (APTR)Window;
  880.  
  881.                 switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_RETRY_IGNORE_QUIT_TXT),Error))
  882.                 {
  883.                     case 1:        goto OpenLoop;
  884.                     case 2:        break;
  885.                     case 0:        Terminated = TRUE;
  886.                 }
  887.  
  888.                 ThisProcess -> pr_WindowPtr = OldPtr;
  889.             }
  890.             else
  891.             {
  892.                 if(SerialMessage)
  893.                 {
  894.                     MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SerialMessage);
  895.  
  896.                     SerialMessage = NULL;
  897.                 }
  898.  
  899.                 ResetSerial = FALSE;
  900.             }
  901.  
  902.             ReleaseWindows();
  903.         }
  904.  
  905.             /* We are to release the serial.device (or
  906.              * whatever we are using) for some reason.
  907.              */
  908.  
  909.         if(ReleaseSerial)
  910.         {
  911.             APTR OldPtr = ThisProcess -> pr_WindowPtr;
  912.  
  913.             ThisProcess -> pr_WindowPtr = (APTR)Window;
  914.  
  915.                 /* This might happen if an ARexx user
  916.                  * released the serial device and
  917.                  * failed to reopen it.
  918.                  */
  919.  
  920.             if(!ReadPort)
  921.                 goto OpenIt;
  922.  
  923.             ClearSerial();
  924.  
  925.             DeleteSerial();
  926.  
  927.             BlockWindows();
  928.  
  929.             if(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_UNIT_RESET_AND_RELEASED_TXT),LocaleString(MSG_TERMMAIN_RETURN_QUIT_TXT),Config . SerialDevice,Config . UnitNumber))
  930.             {
  931.                 UBYTE *Error;
  932.  
  933. OpenIt:                if(Error = CreateSerial())
  934.                 {
  935.                     DeleteSerial();
  936.  
  937.                     switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_RETRY_IGNORE_QUIT_TXT),Error))
  938.                     {
  939.                         case 1:        goto OpenIt;
  940.                         case 2:        break;
  941.                         case 0:        Terminated = TRUE;
  942.                     }
  943.                 }
  944.                 else
  945.                 {
  946.                     if(SerialMessage)
  947.                     {
  948.                         MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SerialMessage);
  949.  
  950.                         SerialMessage = NULL;
  951.                     }
  952.                 }
  953.             }
  954.             else
  955.                 Terminated = TRUE;
  956.  
  957.             ReleaseSerial = FALSE;
  958.  
  959.             ThisProcess -> pr_WindowPtr = OldPtr;
  960.  
  961.             ReleaseWindows();
  962.         }
  963.  
  964.             /* Send the startup macro if necessary. */
  965.  
  966.         if(SendStartup && Online)
  967.         {
  968.             if(Config . StartupMacro[0])
  969.                 SerialCommand(Config . StartupMacro);
  970.  
  971.             SendStartup = FALSE;
  972.         }
  973.  
  974.             /* Somebody told us to re-open the display
  975.              * (changed the terminal emulation/colour
  976.              * mode).
  977.              */
  978.  
  979.         if(ResetDisplay)
  980.         {
  981.             UBYTE *Result;
  982.  
  983.                 /* Delete the display (if possible).
  984.                  * This will go wrong if there
  985.                  * are any visitor windows on our
  986.                  * screen.
  987.                  */
  988.  
  989.             if(DeleteDisplay())
  990.             {
  991.                 if(Result = CreateDisplay(FALSE))
  992.                 {
  993.                     ThisProcess -> pr_WindowPtr = (APTR)Window;
  994.  
  995.                     MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Result);
  996.  
  997.                     Terminated = TRUE;
  998.                 }
  999.  
  1000.                 BumpWindow(Window);
  1001.  
  1002.                 PubScreenStuff();
  1003.             }
  1004.             else
  1005.             {
  1006.                 CopyMem(&PrivateConfig,&Config,sizeof(struct Configuration));
  1007.  
  1008.                 BlockWindows();
  1009.  
  1010.                 MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(MSG_TERMMAIN_CANNOT_CLOSE_SCREEN_YET_TXT));
  1011.  
  1012.                 ReleaseWindows();
  1013.             }
  1014.  
  1015.             ResetDisplay = FALSE;
  1016.  
  1017.             if(Blocking)
  1018.             {
  1019.                 Blocking = FALSE;
  1020.  
  1021.                 continue;
  1022.             }
  1023.         }
  1024.  
  1025.             /* Set up the signal bits to wait for. */
  1026.  
  1027.         SavageSignals = XEM_Signal;
  1028.  
  1029.             /* The serial line is active. */
  1030.  
  1031.         if(Status != STATUS_HOLDING && ReadPort)
  1032.             SavageSignals |= SIG_SERIAL;
  1033.  
  1034.             /* The packet window is still open. */
  1035.  
  1036.         if(PacketWindow)
  1037.             SavageSignals |= SIG_PACKET;
  1038.  
  1039.             /* The review buffer window is open. */
  1040.  
  1041.         if(ReviewPort)
  1042.             SavageSignals |= SIG_REVIEW;
  1043.  
  1044.             /* Wait for input events to occur. */
  1045.  
  1046.         SignalSet = Wait(SIG_WINDOW | SIG_REXX | SIG_AUDIO | SIG_CLIP | SavageSignals);
  1047.     }
  1048.  
  1049.         /* Shut down the transfer panel if any. */
  1050.  
  1051.     if(TransferWindow)
  1052.     {
  1053.         if(DidTransfer)
  1054.         {
  1055.             if(SendAbort && UsesZModem)
  1056.                 SerWrite(ZModemCancel,20);
  1057.         }
  1058.  
  1059.         DeleteTransferPanel();
  1060.     }
  1061.  
  1062.         /* User wants to quit term, so let's try to close
  1063.          * our magnificient screen and exit.
  1064.          */
  1065.  
  1066.     if(Screen)
  1067.     {
  1068.         struct List        *PubScreenList;
  1069.         struct PubScreenNode    *ScreenNode;
  1070.  
  1071.             /* Lock the list of public screens. */
  1072.  
  1073.         PubScreenList = LockPubScreenList();
  1074.  
  1075.             /* Scan the list and try to find our
  1076.              * private node.
  1077.              */
  1078.  
  1079.         for(ScreenNode = (struct PubScreenNode *)PubScreenList -> lh_Head ; ScreenNode -> psn_Node . ln_Succ ; ScreenNode = (struct PubScreenNode *)ScreenNode -> psn_Node . ln_Succ)
  1080.         {
  1081.             if(ScreenNode -> psn_Screen == Screen)
  1082.                 break;
  1083.         }
  1084.  
  1085.         if(ScreenNode)
  1086.         {
  1087.                 /* Okay, we know who and where we are,
  1088.                  * check the number of visitor windows
  1089.                  * currently open on our screen.
  1090.                  */
  1091.  
  1092.             if(ScreenNode -> psn_VisitorCount)
  1093.             {
  1094.                     /* No chance, don't close
  1095.                      * the screen now.
  1096.                      */
  1097.  
  1098.                 UnlockPubScreenList();
  1099.  
  1100.                 BlockWindows();
  1101.  
  1102.                 MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(MSG_TERMMAIN_CANNOT_CLOSE_SCREEN_YET_TXT));
  1103.  
  1104.                 ReleaseWindows();
  1105.  
  1106.                 Terminated = FALSE;
  1107.  
  1108.                 goto Loop;
  1109.             }
  1110.         }
  1111.  
  1112.         UnlockPubScreenList();
  1113.     }
  1114.  
  1115.         /* Send the modem exit command, shut down the
  1116.          * serial.device and close all resources.
  1117.          */
  1118.  
  1119.     SerialCommand(Config . ModemExit);
  1120.  
  1121.     ClearSerial();
  1122.  
  1123.     LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_PROGRAM_TERMINATED_TXT));
  1124.  
  1125.     Say(LocaleString(MSG_TERMMAIN_BYE_BYE_TXT));
  1126.  
  1127.     if(!ThisProcess -> pr_CLI)
  1128.         CloseAll();
  1129. }
  1130.  
  1131.     /* HandleWindow():
  1132.      *
  1133.      *    This funny part checks the window(s) for incoming
  1134.      *    user input. Menus are handled elsewhere.
  1135.      */
  1136.  
  1137. BYTE
  1138. HandleWindow()
  1139. {
  1140.     struct IntuiMessage    *Massage;
  1141.     ULONG             Class,Code,Qualifier;
  1142.     LONG             MouseX,MouseY,Len;
  1143.     struct Gadget        *Gadget;
  1144.     UBYTE             Char,InputBuffer[257];
  1145.  
  1146.         /* Any news in the mail? */
  1147.  
  1148.     if(Massage = (struct IntuiMessage *)GT_GetIMsg(Window -> UserPort))
  1149.     {
  1150.             /* Pick up the pieces. */
  1151.  
  1152.         Class        = Massage -> Class;
  1153.         Code        = Massage -> Code;
  1154.         Qualifier    = Massage -> Qualifier;
  1155.  
  1156.         MouseX        = Massage -> MouseX;
  1157.         MouseY        = Massage -> MouseY;
  1158.  
  1159.         Gadget        = (struct Gadget *)Massage -> IAddress;
  1160.  
  1161.         if(Class == IDCMP_RAWKEY)
  1162.         {
  1163.                 /* Perform key conversion. */
  1164.  
  1165.             if(XEmulatorBase)
  1166.             {
  1167.                 if(Len = XEmulatorUserMon(XEM_IO,InputBuffer,256,Massage))
  1168.                     Char = InputBuffer[0];
  1169.             }
  1170.             else
  1171.                 Char = KeyConvert(Massage,InputBuffer,&Len);
  1172.         }
  1173.  
  1174.         GT_ReplyIMsg(Massage);
  1175.  
  1176.             /* The following messages probably
  1177.              * originate from the fast! macro
  1178.              * panel.
  1179.              */
  1180.  
  1181.         if(FastWindow)
  1182.         {
  1183.                 /* Close the window. */
  1184.  
  1185.             if(Class == IDCMP_CLOSEWINDOW)
  1186.                 CloseFastWindow();
  1187.  
  1188.                 /* Window size has changed for some reason. */
  1189.  
  1190.             if(Class == IDCMP_NEWSIZE)
  1191.             {
  1192.                 if(FastWindow -> Height != Screen -> WBorTop + Screen -> Font -> ta_YSize + 1)
  1193.                 {
  1194.                     RefreshFastWindow(FastWindow -> Height);
  1195.  
  1196.                     RefreshWindowFrame(FastWindow);
  1197.                 }
  1198.             }
  1199.  
  1200.                 /* User has selected an item. */
  1201.  
  1202.             if(Class == IDCMP_GADGETUP)
  1203.             {
  1204.                 struct MacroNode *Node = GetFastMacro(Code);
  1205.  
  1206.                 if(Node)
  1207.                 {
  1208.                     if(Node -> mn_Code[0])
  1209.                         SerialCommand(Node -> mn_Code);
  1210.                 }
  1211.             }
  1212.         }
  1213.  
  1214.             /* This looks like a raw, or better, now cooked key. */
  1215.  
  1216.         if(Class == IDCMP_RAWKEY && Len)
  1217.         {
  1218.                 /* VT100 prefers to handle
  1219.                  * the numeric keypad differently
  1220.                  * in applications mode.
  1221.                  */
  1222.  
  1223.             if(Qualifier & IEQUALIFIER_NUMERICPAD)
  1224.             {
  1225.                 if(HandleCursor(Char))
  1226.                     goto SkipIt;
  1227.             }
  1228.  
  1229.                 /* If input is not a control
  1230.                  * character, such as F-keys,
  1231.                  * cursor keys, etc. process
  1232.                  * it as usual.
  1233.                  */
  1234.  
  1235.             if(!IsControl(Char))
  1236.             {
  1237.                 WORD    i;
  1238.                 UBYTE    c;
  1239.  
  1240.                     /* Run down the contents of
  1241.                      * the key result string.
  1242.                      */
  1243.  
  1244.                 for(i = 0 ; i < Len ; i++)
  1245.                 {
  1246.                     if(Config . StripBit8)
  1247.                         c = InputBuffer[i] & 0x7F;
  1248.                     else
  1249.                         c = InputBuffer[i];
  1250.  
  1251.                         /* Restart serial line
  1252.                          * after XON.
  1253.                          */
  1254.  
  1255.                     if(Status == STATUS_HOLDING)
  1256.                     {
  1257.                         if(c == XOF)
  1258.                         {
  1259.                             SerWrite(&c,1);
  1260.  
  1261.                             Status = STATUS_READY;
  1262.                         }
  1263.                         else
  1264.                             DoSomeBeep();
  1265.                     }
  1266.                     else
  1267.                     {
  1268.                             /* Convert chars
  1269.                              * as approriate.
  1270.                              */
  1271.  
  1272.                         if(c == '\n')
  1273.                         {
  1274.                             switch(Config . SendLF)
  1275.                             {
  1276.                                 case LF_IGNORE:    break;
  1277.  
  1278.                                 case LF_ASLF:    goto SendIt;
  1279.  
  1280.                                 case LF_ASLFCR:    SerWrite("\n\r",2);
  1281.                                         break;
  1282.                             }
  1283.  
  1284.                             continue;
  1285.                         }
  1286.  
  1287.                         if(c == '\r')
  1288.                         {
  1289.                             switch(Config . SendCR)
  1290.                             {
  1291.                                 case CR_IGNORE:    break;
  1292.  
  1293.                                 case CR_ASCR:    goto SendIt;
  1294.  
  1295.                                 case CR_ASCRLF:    SerWrite("\r\n",2);
  1296.                                         break;
  1297.                             }
  1298.  
  1299.                             continue;
  1300.                         }
  1301.  
  1302.                             /* Stop in/output. */
  1303.  
  1304.                         if(c == XON)
  1305.                         {
  1306.                             if(Config . PassThrough)
  1307.                             {
  1308.                                 SerWrite(&c,1);
  1309.  
  1310.                                 continue;
  1311.                             }
  1312.                             else
  1313.                             {
  1314.                                 if(Config . Handshaking == HANDSHAKING_XONXOFF)
  1315.                                     Status = STATUS_HOLDING;
  1316.                             }
  1317.                         }
  1318.  
  1319.                             /* Restart in/output. */
  1320.  
  1321.                         if(c == XOF)
  1322.                         {
  1323.                             if(Config . PassThrough)
  1324.                             {
  1325.                                 SerWrite(&c,1);
  1326.  
  1327.                                 continue;
  1328.                             }
  1329.                         }
  1330.  
  1331.                             /* Convert special
  1332.                              * Amiga characters into
  1333.                              * alien IBM dialect.
  1334.                              */
  1335.  
  1336. SendIt:                        if(Config . Font == FONT_IBM)
  1337.                         {
  1338.                             if(IBMConversion[c])
  1339.                                 SerWrite(&IBMConversion[c],1);
  1340.                             else
  1341.                                 SerWrite(&c,1);
  1342.                         }
  1343.                         else
  1344.                             SerWrite(&c,1);
  1345.                     }
  1346.                 }
  1347.             }
  1348.             else
  1349.             {
  1350.                     /* Send keyboard macro commands
  1351.                      * or perform cursor functions.
  1352.                      */
  1353.  
  1354.                 if(Char >= FN1 && Char <= F10)
  1355.                 {
  1356.                     if(Qualifier & IEQUALIFIER_CONTROL)
  1357.                         SerialCommand(MacroKeys -> Keys[3][Char - FN1]);
  1358.                     else
  1359.                     {
  1360.                         if(Qualifier & (IEQUALIFIER_LALT|IEQUALIFIER_RALT))
  1361.                             SerialCommand(MacroKeys -> Keys[2][Char - FN1]);
  1362.                         else
  1363.                         {
  1364.                             if(Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  1365.                                 SerialCommand(MacroKeys -> Keys[1][Char - FN1]);
  1366.                             else
  1367.                                 SerialCommand(MacroKeys -> Keys[0][Char - FN1]);
  1368.                         }
  1369.                     }
  1370.                 }
  1371.                 else
  1372.                     HandleCursor(Char);
  1373.             }
  1374.         }
  1375.  
  1376.             /* Capture characters from the main
  1377.              * screen.
  1378.              */
  1379.  
  1380.         if(Class == IDCMP_MOUSEBUTTONS && !(Code & IECODE_UP_PREFIX))
  1381.         {
  1382.             if(Code == SELECTDOWN && (Qualifier & (IEQUALIFIER_LALT|IEQUALIFIER_RALT)) && (Qualifier & IEQUALIFIER_LEFTBUTTON))
  1383.             {
  1384.                 WORD DeltaX,DeltaY;
  1385.  
  1386.                 DeltaX = (MouseX >> 3) - CursorX;
  1387.                 DeltaY = (MouseY >> 3) - CursorY;
  1388.  
  1389.                 if(DeltaX || DeltaY)
  1390.                 {
  1391.                     if(DeltaX > 0)
  1392.                     {
  1393.                         DeltaX++;
  1394.  
  1395.                         while(DeltaX--)
  1396.                             SerWrite("\33[C",3);
  1397.                     }
  1398.  
  1399.                     if(DeltaX < 0)
  1400.                     {
  1401.                         while(DeltaX++)
  1402.                             SerWrite("\33[D",3);
  1403.                     }
  1404.  
  1405.                     if(DeltaY > 0)
  1406.                     {
  1407.                         DeltaY++;
  1408.  
  1409.                         while(DeltaY--)
  1410.                             SerWrite("\33[B",3);
  1411.                     }
  1412.  
  1413.                     if(DeltaY < 0)
  1414.                     {
  1415.                         while(DeltaY++)
  1416.                             SerWrite("\33[A",3);
  1417.                     }
  1418.                 }
  1419.             }
  1420.             else
  1421.             {
  1422.                 if(!XEmulatorBase || Config . Emulation != EMULATION_EXTERNAL)
  1423.                 {
  1424.                     BYTE SingleChar,Xerox;
  1425.  
  1426.                         /* We want to know where the mouse
  1427.                          * moves...
  1428.                          */
  1429.  
  1430.                     ReportMouse(TRUE,Window);
  1431.  
  1432.                         /* Pick a single character. */
  1433.  
  1434.                     if(Qualifier & IEQUALIFIER_CONTROL)
  1435.                         SingleChar = TRUE;
  1436.                     else
  1437.                         SingleChar = FALSE;
  1438.  
  1439.                         /* Xerox style snapping (feed into
  1440.                          * input stream after selection).
  1441.                          */
  1442.  
  1443.                     if(Code == MIDDLEDOWN || (Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)))
  1444.                         Xerox = TRUE;
  1445.                     else
  1446.                         Xerox = FALSE;
  1447.  
  1448.                     RasterClip(SingleChar,Xerox);
  1449.  
  1450.                     ReportMouse(FALSE,Window);
  1451.                 }
  1452.             }
  1453.         }
  1454.  
  1455.             /* A menu item was selected. */
  1456.  
  1457. SkipIt:        if(Class == IDCMP_MENUPICK)
  1458.             HandleMenu(Code,Qualifier);
  1459.  
  1460.         return(TRUE);
  1461.     }
  1462.  
  1463.     return(FALSE);
  1464. }
  1465.  
  1466.     /* TransferCleanup():
  1467.      *
  1468.      * We did a file transfer (auto-download?) and
  1469.      * will need to close the transfer window.
  1470.      */
  1471.  
  1472. VOID
  1473. TransferCleanup()
  1474. {
  1475.     if(DidTransfer)
  1476.     {
  1477.         WakeUp(TransferWindow,TRUE);
  1478.  
  1479.         DeleteTransferPanel();
  1480.  
  1481.         if(SendAbort && UsesZModem)
  1482.             SerWrite(ZModemCancel,20);
  1483.  
  1484.         SendAbort = FALSE;
  1485.  
  1486.         if(Config . DownloadMacro[0])
  1487.             SerialCommand(Config . DownloadMacro);
  1488.  
  1489.         Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  1490.  
  1491.         DidTransfer = FALSE;
  1492.     }
  1493.     else
  1494.     {
  1495.         WaitTime(3,0);
  1496.  
  1497.         DeleteTransferPanel();
  1498.     }
  1499.  
  1500.     ReleaseWindows();
  1501. }
  1502.  
  1503.     /* HandleSerial():
  1504.      *
  1505.      *    Handle the data coming in from the serial line.
  1506.      */
  1507.  
  1508. BYTE
  1509. HandleSerial()
  1510. {
  1511.     if(ReadPort && !ReleaseSerial && !Terminated)
  1512.     {
  1513.         BYTE Return = FALSE;
  1514.  
  1515.         if(HostReadBuffer)
  1516.         {
  1517.             LONG Length;
  1518.  
  1519.             if(Length = XProtocolHostMon(XprIO,HostReadBuffer,0,Config . SerBuffSize))
  1520.             {
  1521.                 ConProcess(ReadBuffer,Length);
  1522.  
  1523.                 Return = TRUE;
  1524.             }
  1525.         }
  1526.  
  1527.             /* We are XON'ed or the serial line was shut down. */
  1528.  
  1529.         if(Status != STATUS_HOLDING && !Blocking)
  1530.         {
  1531.                 /* Any news? */
  1532.  
  1533.             if(CheckIO(ReadRequest))
  1534.             {
  1535.                 LONG Length;
  1536.  
  1537.                 if(WaitIO(ReadRequest))
  1538.                 {
  1539.                     ReadRequest -> IOSer . io_Command    = CMD_READ;
  1540.                     ReadRequest -> IOSer . io_Data        = ReadBuffer;
  1541.                     ReadRequest -> IOSer . io_Length     = 1;
  1542.  
  1543.                     SetSignal(0,SIG_SERIAL);
  1544.  
  1545.                     SendIO(ReadRequest);
  1546.  
  1547.                     return(Return);
  1548.                 }
  1549.  
  1550.                 if(XProtocolBase)
  1551.                 {
  1552.                         /* Process the data if necessary (XPR-function). */
  1553.  
  1554.                     if(TransferBits & XPRS_HOSTMON)
  1555.                     {
  1556.                         LONG Result = XProtocolHostMon(XprIO,ReadBuffer,1,1);
  1557.  
  1558.                         if(TransferWindow)
  1559.                             TransferCleanup();
  1560.  
  1561.                         if(!Result)
  1562.                             goto Loop;
  1563.                     }
  1564.                 }
  1565.  
  1566.                     /* Send the byte to the console. */
  1567.  
  1568.                 ConProcess(ReadBuffer,1);
  1569.  
  1570.                     /* Loop until all data has been processed. */
  1571.  
  1572. Loop:                do
  1573.                 {
  1574.                         /* Check how many bytes are still in
  1575.                          * the serial buffer.
  1576.                          */
  1577.  
  1578.                     WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  1579.  
  1580.                     DoIO(WriteRequest);
  1581.  
  1582.                     if(Length = WriteRequest -> IOSer . io_Actual)
  1583.                     {
  1584.                         if(Length > Config . SerBuffSize)
  1585.                             Length = Config . SerBuffSize;
  1586.  
  1587.                         ReadRequest -> IOSer . io_Command    = CMD_READ;
  1588.                         ReadRequest -> IOSer . io_Data        = ReadBuffer;
  1589.                         ReadRequest -> IOSer . io_Length    = Length;
  1590.  
  1591.                         if(!DoIO(ReadRequest))
  1592.                         {
  1593.                             if(XProtocolBase)
  1594.                             {
  1595.                                     /* Process the serial data if
  1596.                                      * necessary (XPR-stuff).
  1597.                                      */
  1598.  
  1599.                                 if(TransferBits & XPRS_HOSTMON)
  1600.                                 {
  1601.                                     Length = XProtocolHostMon(XprIO,ReadBuffer,Length,Config . SerBuffSize);
  1602.  
  1603.                                     if(TransferWindow)
  1604.                                         TransferCleanup();
  1605.  
  1606.                                     if(!Length)
  1607.                                     {
  1608.                                         Length = 1;
  1609.  
  1610.                                         continue;
  1611.                                     }
  1612.                                 }
  1613.                             }
  1614.  
  1615.                                 /* Send the data to the console. */
  1616.  
  1617.                             ConProcess(ReadBuffer,Length);
  1618.                         }
  1619.                     }
  1620.                 }
  1621.                 while(Length);
  1622.  
  1623.                     /* Ask for another byte. */
  1624.  
  1625.                 ReadRequest -> IOSer . io_Command    = CMD_READ;
  1626.                 ReadRequest -> IOSer . io_Data        = ReadBuffer;
  1627.                 ReadRequest -> IOSer . io_Length     = 1;
  1628.  
  1629.                 SetSignal(0,SIG_SERIAL);
  1630.  
  1631.                 SendIO(ReadRequest);
  1632.  
  1633.                 return(TRUE);
  1634.             }
  1635.         }
  1636.  
  1637.         return(Return);
  1638.     }
  1639.  
  1640.     return(FALSE);
  1641. }
  1642.  
  1643.     /* HandleCode(ULONG Code,ULONG Qualifier,struct MenuItem *MenuItem):
  1644.      *
  1645.      *    Handle each function associated with a menu code.
  1646.      */
  1647.  
  1648. VOID
  1649. HandleCode(ULONG Code,ULONG Qualifier,struct MenuItem *MenuItem)
  1650. {
  1651.     STATIC UBYTE         NumberBuffer[256];
  1652.  
  1653.     struct FileRequester    *FileRequest;
  1654.     UBYTE             DummyBuffer[256],
  1655.                 *DummyChar;
  1656.     BYTE             OldStatus = Status;
  1657.  
  1658.     LONG             Size;
  1659.     BPTR             SomeFile;
  1660.     APTR             OldPtr;
  1661.  
  1662.     switch(Code)
  1663.     {
  1664.             /* Say who we are. */
  1665.  
  1666.         case MEN_ABOUT:        BlockWindows();
  1667.  
  1668.                     ShowInfo(FALSE);
  1669.  
  1670.                     ReleaseWindows();
  1671.  
  1672.                     break;
  1673.  
  1674.         case MEN_ICONIFY:    DoIconify = TRUE;
  1675.  
  1676.                     break;
  1677.  
  1678.             /* Open the preferences settings. */
  1679.  
  1680.         case MEN_OPEN:        BlockWindows();
  1681.  
  1682.                     strcpy(DummyBuffer,LastConfig);
  1683.  
  1684.                     DummyChar = PathPart(DummyBuffer);
  1685.  
  1686.                     *DummyChar = 0;
  1687.  
  1688.                     if(FileRequest = GetFile(LocaleString(MSG_TERMMAIN_OPEN_PREFERENCES_TXT),DummyBuffer,FilePart(LastConfig),DummyBuffer,"term#?",FALSE,FALSE,FALSE,NULL))
  1689.                     {
  1690.                         if(ReadIFFData(DummyBuffer,&PrivateConfig,sizeof(struct Configuration),'PREF'))
  1691.                         {
  1692.                             swmem(&PrivateConfig,&Config,sizeof(struct Configuration));
  1693.  
  1694.                             strcpy(DummyBuffer,LastConfig);
  1695.  
  1696.                             ConfigSetup();
  1697.                         }
  1698.                         else
  1699.                             MyEasyRequest(Window,LocaleString(MSG_GLOBAL_ERROR_OPENING_FILE_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),DummyBuffer);
  1700.  
  1701.                         FreeAslRequest(FileRequest);
  1702.                     }
  1703.  
  1704.                     ReleaseWindows();
  1705.  
  1706.                     break;
  1707.  
  1708.             /* Save the terminal preferences. */
  1709.  
  1710.         case MEN_SAVE:        if(LastConfig[0])
  1711.                     {
  1712.                         BlockWindows();
  1713.  
  1714.                         if(!WriteIFFData(LastConfig,&Config,sizeof(struct Configuration),'PREF'))
  1715.                             MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_ERROR_WRITING_PREFERENCES_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LastConfig);
  1716.  
  1717.                         ReleaseWindows();
  1718.                     }
  1719.  
  1720.                     break;
  1721.  
  1722.             /* Save the terminal preferences to a
  1723.              * given file name.
  1724.              */
  1725.  
  1726.         case MEN_SAVEAS:    BlockWindows();
  1727.  
  1728.                     strcpy(DummyBuffer,LastConfig);
  1729.  
  1730.                     DummyChar = PathPart(DummyBuffer);
  1731.  
  1732.                     *DummyChar = 0;
  1733.  
  1734.                     if(FileRequest = GetFile(LocaleString(MSG_TERMMAIN_SAVE_PREFERENCES_AS_TXT),DummyBuffer,FilePart(LastConfig),DummyBuffer,"term#?",TRUE,FALSE,FALSE,NULL))
  1735.                     {
  1736.                         if(WriteIFFData(DummyBuffer,&Config,sizeof(struct Configuration),'PREF'))
  1737.                             strcpy(LastConfig,DummyBuffer);
  1738.                         else
  1739.                             MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_ERROR_WRITING_PREFERENCES_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),DummyBuffer);
  1740.  
  1741.                         FreeAslRequest(FileRequest);
  1742.                     }
  1743.  
  1744.                     ReleaseWindows();
  1745.  
  1746.                     break;
  1747.  
  1748.             /* Print the screen (pure ASCII). */
  1749.  
  1750.         case MEN_PRINTSCREEN:    BlockWindows();
  1751.  
  1752.                     if(!XEmulatorBase || Config . Emulation != EMULATION_EXTERNAL)
  1753.                         PrintRegion(0,LastLine + 1);
  1754.                     else
  1755.                         MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_NO_DATA_TO_PRINT_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  1756.  
  1757.                     ReleaseWindows();
  1758.  
  1759.                     break;
  1760.  
  1761.             /* Terminate the program. */
  1762.  
  1763.         case MEN_QUIT:        if(Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  1764.                         Terminated = TRUE;
  1765.                     else
  1766.                     {
  1767.                         BlockWindows();
  1768.  
  1769.                         OldPtr = ThisProcess -> pr_WindowPtr;
  1770.  
  1771.                         ThisProcess -> pr_WindowPtr = (APTR)Window;
  1772.  
  1773.                         if(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_REALLY_QUIT_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT)))
  1774.                             Terminated = TRUE;
  1775.  
  1776.                         ThisProcess -> pr_WindowPtr = OldPtr;
  1777.  
  1778.                         ReleaseWindows();
  1779.                     }
  1780.  
  1781.                     break;
  1782.  
  1783.             /* Set the name we will use to open the
  1784.              * default console output window for
  1785.              * AmigaDOS commands and ARexx scripts.
  1786.              */
  1787.  
  1788.         case MEN_SETCONSOLE:    BlockWindows();
  1789.  
  1790.                     if(xpr_gets(LocaleString(MSG_TERMMAIN_SET_CONSOLE_WINDOW_TXT),WindowName))
  1791.                         SetEnvDOS("TERMWINDOW",WindowName);
  1792.  
  1793.                     ReleaseWindows();
  1794.  
  1795.                     break;
  1796.  
  1797.             /* Execute an AmigaDOS command. */
  1798.  
  1799.         case MEN_DOSCOMMAND:    BlockWindows();
  1800.  
  1801.                     DummyBuffer[0] = 0;
  1802.  
  1803.                         /* Enter the name of the command. */
  1804.  
  1805.                     if(GetString(LocaleString(MSG_TERMMAIN_ENTER_AMIGADOS_COMMAND_TXT),DummyBuffer))
  1806.                         SendAmigaDOSCommand(DummyBuffer);
  1807.  
  1808.                     ReleaseWindows();
  1809.  
  1810.                     break;
  1811.  
  1812.             /* Execute an ARexx script command. */
  1813.  
  1814.         case MEN_REXXCOMMAND:    BlockWindows();
  1815.  
  1816.                     DummyBuffer[0] = 0;
  1817.  
  1818.                         /* Get the rexx file name/program. */
  1819.  
  1820.                     if(GetString(LocaleString(MSG_TERMMAIN_ENTER_AREXX_COMMAND_TXT),DummyBuffer))
  1821.                         SendARexxCommand(DummyBuffer);
  1822.  
  1823.                     ReleaseWindows();
  1824.  
  1825.                     break;
  1826.  
  1827.             /* Feed the contents of the clipboard
  1828.              * into the input stream.
  1829.              */
  1830.  
  1831.         case MEN_PASTE:        if(Size = LoadClip(SharedBuffer,256))
  1832.                         SerWrite(SharedBuffer,Size);
  1833.  
  1834.                     break;
  1835.  
  1836.             /* Open the packet window if necessary, else
  1837.              * just activate it.
  1838.              */
  1839.  
  1840.         case MEN_PACKET:    if(!PacketWindow)
  1841.                         CreatePacketWindow();
  1842.                     else
  1843.                         ActivateWindow(PacketWindow);
  1844.  
  1845.                     break;
  1846.  
  1847.             /* Toggle the presence of the fast! macro panel. */
  1848.  
  1849.         case MEN_FASTMACROPANEL:if(FastWindow)
  1850.                         CloseFastWindow();
  1851.                     else
  1852.                         OpenFastWindow();
  1853.  
  1854.                     break;
  1855.  
  1856.             /* Clear the contents of the scrollback
  1857.              * buffer.
  1858.              */
  1859.  
  1860.         case MEN_CLEARBUFFER:    if(Lines)
  1861.                     {
  1862.                         BlockWindows();
  1863.  
  1864.                         if(Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  1865.                             ClearBuffer();
  1866.                         else
  1867.                         {
  1868.                             if(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_BUFFER_STILL_HOLDS_LINES_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT),Lines))
  1869.                                 ClearBuffer();
  1870.                         }
  1871.  
  1872.                         UpdateReview(TRUE);
  1873.  
  1874.                         ReleaseWindows();
  1875.                     }
  1876.  
  1877.                     break;
  1878.  
  1879.             /* Display the scrollback buffer.
  1880.              * Notify the scrollback task or
  1881.              * fire it off if approriate.
  1882.              */
  1883.  
  1884.         case MEN_DISPLAYBUFFER:    if(Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  1885.                         CreateReview();
  1886.                     else
  1887.                     {
  1888.                         if(BufferProcess)
  1889.                             Signal(BufferProcess,SIGBREAKF_CTRL_D);
  1890.                         else
  1891.                         {
  1892.                             if(BufferProcess = (struct Process *)CreateNewProcTags(
  1893.                                 NP_Entry,    BufferServer,
  1894.                                 NP_Name,    "term buffer process",
  1895.                                 NP_Priority,    0,
  1896.                                 NP_StackSize,    8192,
  1897.                                 NP_WindowPtr,    -1,
  1898.                             TAG_END))
  1899.                                 Wait(SIGBREAKF_CTRL_C);
  1900.  
  1901.                             if(!BufferProcess)
  1902.                             {
  1903.                                 BlockWindows();
  1904.  
  1905.                                 MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_UNABLE_TO_CREATE_BUFFER_TASK_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  1906.  
  1907.                                 ReleaseWindows();
  1908.                             }
  1909.                         }
  1910.                     }
  1911.  
  1912.                     break;
  1913.  
  1914.  
  1915.             /* Close the buffer display. */
  1916.  
  1917.         case MEN_CLOSEBUFFER:    if(Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  1918.                         DeleteReview();
  1919.                     else
  1920.                     {
  1921.                         if(BufferProcess)
  1922.                             Signal(BufferProcess,SIGBREAKF_CTRL_C);
  1923.                     }
  1924.  
  1925.                     break;
  1926.  
  1927.             /* Is the buffer to be frozen? */
  1928.  
  1929.         case MEN_FREEZEBUFFER:    if(MenuItem -> Flags & CHECKED)
  1930.                         BufferFrozen = TRUE;
  1931.                     else
  1932.                         BufferFrozen = FALSE;
  1933.  
  1934.                     break;
  1935.  
  1936.             /* Load the buffer contents from a file. */
  1937.  
  1938.         case MEN_LOADBUFFER:    BlockWindows();
  1939.  
  1940.                     if(FileRequest = GetFile(LocaleString(MSG_TERMMAIN_LOAD_BUFFER_TXT),"","",DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_GLOBAL_LOAD_TXT)))
  1941.                     {
  1942.                         if(GetFileSize(DummyBuffer))
  1943.                         {
  1944.                             if(SomeFile = Open(DummyBuffer,MODE_OLDFILE))
  1945.                             {
  1946.                                 if(Lines)
  1947.                                 {
  1948.                                     switch(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_BUFFER_STILL_HOLDS_LINES_TXT),LocaleString(MSG_TERMMAIN_DISCARD_APPPEND_CANCEL_TXT),Lines))
  1949.                                     {
  1950.                                         case 1:    ClearBuffer();
  1951.                                             break;
  1952.  
  1953.                                         case 2:    break;
  1954.  
  1955.                                         case 0:    Close(SomeFile);
  1956.                                             SomeFile = NULL;
  1957.                                             break;
  1958.                                     }
  1959.                                 }
  1960.  
  1961.                                 if(SomeFile)
  1962.                                 {
  1963.                                     LONG Len;
  1964.  
  1965.                                     LineRead(NULL,NULL,NULL);
  1966.  
  1967.                                     while(Len = LineRead(SomeFile,DummyBuffer,80))
  1968.                                         StoreBuffer(DummyBuffer,Len);
  1969.  
  1970.                                     Close(SomeFile);
  1971.                                 }
  1972.                             }
  1973.                         }
  1974.  
  1975.                         FreeAslRequest(FileRequest);
  1976.                     }
  1977.  
  1978.                     ReleaseWindows();
  1979.                     break;
  1980.  
  1981.             /* Save the contents of the scrollback
  1982.              * buffer to a file (line by line).
  1983.              */
  1984.  
  1985.         case MEN_SAVEBUFFER:    BlockWindows();
  1986.  
  1987.                     if(!Lines)
  1988.                         MyEasyRequest(Window,LocaleString(MSG_GLOBAL_NOTHING_IN_THE_BUFFER_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  1989.                     else
  1990.                     {
  1991.                         if(FileRequest = GetFile(LocaleString(MSG_TERMMAIN_SAVE_BUFFER_TXT),"","",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT)))
  1992.                         {
  1993.                             SomeFile = NULL;
  1994.  
  1995.                                 /* If the file we are about
  1996.                                  * to create already exists,
  1997.                                  * ask the user whether we are
  1998.                                  * to create, append or skip
  1999.                                  * the file.
  2000.                                  */
  2001.  
  2002.                             if(GetFileSize(DummyBuffer))
  2003.                             {
  2004.                                 switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
  2005.                                 {
  2006.                                     case 1:    SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  2007.                                         break;
  2008.  
  2009.                                     case 2:    if(SomeFile = Open(DummyBuffer,MODE_READWRITE))
  2010.                                         {
  2011.                                             if(Seek(SomeFile,0,OFFSET_END) == -1)
  2012.                                             {
  2013.                                                 Close(SomeFile);
  2014.  
  2015.                                                 SomeFile = NULL;
  2016.                                             }
  2017.                                         }
  2018.  
  2019.                                         break;
  2020.                                 }
  2021.                             }
  2022.                             else
  2023.                                 SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  2024.  
  2025.                             if(!SomeFile)
  2026.                                 MyEasyRequest(Window,LocaleString(MSG_GLOBAL_ERROR_OPENING_FILE_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),DummyBuffer);
  2027.                             else
  2028.                             {
  2029.                                 LONG i,Len;
  2030.  
  2031.                                     /* Obtain the semaphore required
  2032.                                      * to gain access to the line buffer
  2033.                                      */
  2034.  
  2035.                                 ObtainSemaphore(BufferSemaphore);
  2036.  
  2037.                                 for(i = 0 ; i < Lines ; i++)
  2038.                                 {
  2039.                                     Len = ((ULONG *)BufferLines[i])[-1];
  2040.  
  2041.                                     if(Len)
  2042.                                     {
  2043.                                         if(FWrite(SomeFile,BufferLines[i],Len,1) != 1)
  2044.                                             break;
  2045.                                     }
  2046.  
  2047.                                     if(FPrintf(SomeFile,"\n") < 1)
  2048.                                         break;
  2049.                                 }
  2050.  
  2051.                                 ReleaseSemaphore(BufferSemaphore);
  2052.  
  2053.                                 Close(SomeFile);
  2054.  
  2055.                                 SetProtection(DummyBuffer,FIBF_EXECUTE);
  2056.                             }
  2057.  
  2058.                             FreeAslRequest(FileRequest);
  2059.                         }
  2060.                     }
  2061.  
  2062.                     ReleaseWindows();
  2063.  
  2064.                     break;
  2065.  
  2066.             /* Open/close the terminal capture file. */
  2067.  
  2068.         case MEN_CAPTUREDISK:    if(FileCapture)
  2069.                     {
  2070.                         BufferClose(FileCapture);
  2071.  
  2072.                         MenuItem -> Flags &= ~CHECKED;
  2073.  
  2074.                         FileCapture = NULL;
  2075.  
  2076.                         if(!GetFileSize(CaptureName))
  2077.                             DeleteFile(CaptureName);
  2078.                         else
  2079.                             SetProtection(CaptureName,FIBF_EXECUTE);
  2080.                     }
  2081.                     else
  2082.                     {
  2083.                         BlockWindows();
  2084.  
  2085.                         if(!CaptureName[0])
  2086.                         {
  2087.                             strcpy(CaptureName,Config . CapturePath);
  2088.  
  2089.                             if(!AddPart(CaptureName,LocaleString(MSG_DIALPANEL_CAPTURE_NAME_TXT),256))
  2090.                                 CaptureName[0] = 0;
  2091.                         }
  2092.  
  2093.                         strcpy(DummyBuffer,CaptureName);
  2094.  
  2095.                         DummyChar = PathPart(DummyBuffer);
  2096.  
  2097.                         *DummyChar = 0;
  2098.  
  2099.                         if(FileRequest = GetFile(LocaleString(MSG_TERMMAIN_CAPTURE_TO_DISK_TXT),DummyBuffer,FilePart(CaptureName),DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_OPEN_TXT)))
  2100.                         {
  2101.                             if(GetFileSize(DummyBuffer))
  2102.                             {
  2103.                                 switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
  2104.                                 {
  2105.                                     case 1:    FileCapture = BufferOpen(DummyBuffer,"w");
  2106.                                         break;
  2107.  
  2108.                                     case 2:    FileCapture = BufferOpen(DummyBuffer,"a");
  2109.                                         break;
  2110.  
  2111.                                     case 0:    MenuItem -> Flags &= ~CHECKED;
  2112.                                         goto CapSkip;
  2113.                                 }
  2114.                             }
  2115.                             else
  2116.                                 FileCapture = BufferOpen(DummyBuffer,"w");
  2117.  
  2118.                             if(!FileCapture)
  2119.                             {
  2120.                                 MyEasyRequest(Window,LocaleString(MSG_GLOBAL_ERROR_OPENING_FILE_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),DummyBuffer);
  2121.  
  2122.                                 MenuItem -> Flags &= ~CHECKED;
  2123.                             }
  2124.                             else
  2125.                             {
  2126.                                 strcpy(CaptureName,DummyBuffer);
  2127.  
  2128.                                 MenuItem -> Flags |= CHECKED;
  2129.                             }
  2130.  
  2131.                             FreeAslRequest(FileRequest);
  2132.                         }
  2133.                         else
  2134.                             MenuItem -> Flags &= ~CHECKED;
  2135.  
  2136. CapSkip:                    ReleaseWindows();
  2137.                     }
  2138.  
  2139.                     break;
  2140.  
  2141.             /* Start/terminate the printer
  2142.              * capture.
  2143.              */
  2144.  
  2145.         case MEN_CAPTUREPRINTER:if(PrinterCapture)
  2146.                         ClosePrinterCapture(TRUE);
  2147.                     else
  2148.                         OpenPrinterCapture(FALSE);
  2149.  
  2150.                     break;
  2151.  
  2152.             /* This follows the upload routines.
  2153.              * Text upload makes the xpr_finfo function
  2154.              * identify any file as being a text
  2155.              * file (no voodoo magic yet).
  2156.              */
  2157.  
  2158.         case MEN_UPLOADTEXT:    BinaryTransfer = FALSE;
  2159.  
  2160.             /* The rest of the upload routines. */
  2161.  
  2162.         case MEN_UPLOAD:    BlockWindows();
  2163.  
  2164.                     StartXprSend(BinaryTransfer ? TRANSFER_BINARY : TRANSFER_TEXT);
  2165.  
  2166.                     BinaryTransfer = TRUE;
  2167.  
  2168.                     ReleaseWindows();
  2169.  
  2170.                     break;
  2171.  
  2172.         case MEN_DOWNLOADTEXT:    BinaryTransfer = FALSE;
  2173.  
  2174.             /* Download some files. */
  2175.  
  2176.         case MEN_DOWNLOAD:    BlockWindows();
  2177.  
  2178.                     StartXprReceive(BinaryTransfer ? TRANSFER_BINARY : TRANSFER_TEXT);
  2179.  
  2180.                     BinaryTransfer = TRUE;
  2181.  
  2182.                     ReleaseWindows();
  2183.  
  2184.                     break;
  2185.  
  2186.             /* Set the file transfer options. */
  2187.  
  2188.         case MEN_XFERPROTOCOL:    BlockWindows();
  2189.  
  2190.                     for(;;)
  2191.                     {
  2192.                         XprIO -> xpr_filename = NULL;
  2193.  
  2194.                         NewLibrary = FALSE;
  2195.  
  2196.                             /* Set up the library options. */
  2197.  
  2198.                         if(XProtocolBase)
  2199.                         {
  2200.                             TransferBits = XProtocolSetup(XprIO);
  2201.  
  2202.                                 /* Successful? */
  2203.  
  2204.                             if(!(TransferBits & XPRS_SUCCESS))
  2205.                             {
  2206.                                 MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_SET_UP_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LastXprLibrary);
  2207.  
  2208.                                 CloseLibrary(XProtocolBase);
  2209.  
  2210.                                 XProtocolBase = NULL;
  2211.  
  2212.                                 LastXprLibrary[0] = 0;
  2213.  
  2214.                                 TransferBits = 0;
  2215.  
  2216.                                 break;
  2217.                             }
  2218.                         }
  2219.                         else
  2220.                             xpr_options(0,NULL);
  2221.  
  2222.                             /* Save the options if necessary. */
  2223.  
  2224.                         SaveProtocolOpts();
  2225.  
  2226.                         if(NewLibrary)
  2227.                         {
  2228.                             if(!ProtocolSetup())
  2229.                                 break;
  2230.  
  2231.                             if(strlen(LastXprLibrary) > 39)
  2232.                             {
  2233.                                 MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_NAME_TOO_LONG_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  2234.  
  2235.                                 strcpy(Config . Protocol,FilePart(LastXprLibrary));
  2236.                             }
  2237.                             else
  2238.                                 strcpy(Config . Protocol,LastXprLibrary);
  2239.                         }
  2240.                         else
  2241.                             break;
  2242.                     }
  2243.  
  2244.                     ReleaseWindows();
  2245.  
  2246.                     break;
  2247.  
  2248.             /* Select the transfer protocol; I had hoped
  2249.              * to get rid of this option but xprascii and
  2250.              * the older pre-2.0 standard xpr-libraries
  2251.              * forced it back in.
  2252.              */
  2253.  
  2254.         case MEN_SELECTXFER:    BlockWindows();
  2255.  
  2256.                     if(SelectProtocol(LastXprLibrary,Window))
  2257.                     {
  2258.                         if(ProtocolSetup())
  2259.                         {
  2260.                             if(strlen(LastXprLibrary) > 39)
  2261.                             {
  2262.                                 MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_NAME_TOO_LONG_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  2263.  
  2264.                                 strcpy(Config . Protocol,FilePart(LastXprLibrary));
  2265.                             }
  2266.                             else
  2267.                                 strcpy(Config . Protocol,LastXprLibrary);
  2268.                         }
  2269.                         else
  2270.                         {
  2271.                             strcpy(LastXprLibrary,Config . Protocol);
  2272.  
  2273.                             ProtocolSetup();
  2274.                         }
  2275.                     }
  2276.  
  2277.                     ReleaseWindows();
  2278.  
  2279.                     break;
  2280.  
  2281.             /* These routines simply switch the
  2282.              * transfer library (to xprascii.library)
  2283.              * and perform up/download. To lessen the
  2284.              * confusion both routines have been
  2285.              * implemented as single routines.
  2286.              * After the transfer the control is
  2287.              * returned to the previously selected
  2288.              * transfer library.
  2289.              */
  2290.  
  2291.         case MEN_SEND:        BlockWindows();
  2292.  
  2293.                     if(ASCIISetup())
  2294.                     {
  2295.                         StartXprSend(TRANSFER_ASCII);
  2296.  
  2297.                         ASCIIShutdown();
  2298.                     }
  2299.  
  2300.                     ReleaseWindows();
  2301.  
  2302.                     break;
  2303.  
  2304.         case MEN_RECEIVE:    BlockWindows();
  2305.  
  2306.                     if(ASCIISetup())
  2307.                     {
  2308.                         StartXprReceive(TRANSFER_ASCII);
  2309.  
  2310.                         ASCIIShutdown();
  2311.                     }
  2312.  
  2313.                     ReleaseWindows();
  2314.  
  2315.                     break;
  2316.  
  2317.             /* Edit and transfer a file. */
  2318.  
  2319.         case MEN_EDIT:        BlockWindows();
  2320.  
  2321.                     if(!Config . Editor[0])
  2322.                         GetString(LocaleString(MSG_TERMMAIN_ENTER_NAME_OF_EDITOR_TO_USE_TXT),&Config . Editor[0]);
  2323.  
  2324.                     if(Config . Editor[0])
  2325.                     {
  2326.                         if(FileRequest = GetFile(LocaleString(MSG_TERMMAIN_EDIT_AND_TRANSFER_FILE_TXT),"","",DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_TERMMAIN_EDIT_TXT)))
  2327.                         {
  2328.                             UBYTE CompoundName[512];
  2329.  
  2330.                             strcpy(CompoundName,Config . Editor);
  2331.                             strcat(CompoundName," ");
  2332.                             strcat(CompoundName,DummyBuffer);
  2333.  
  2334.                             SystemTags(CompoundName,TAG_DONE);
  2335.  
  2336.                             BumpWindow(Window);
  2337.  
  2338.                             FreeAslRequest(FileRequest);
  2339.  
  2340.                             if(GetFileSize(DummyBuffer))
  2341.                             {
  2342.                                 BinaryTransfer = FALSE;
  2343.  
  2344.                                 switch(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_TRANSFER_FILE_AS_TXT),LocaleString(MSG_TERMMAIN_ASCII_UPLOAD_CANCEL_TXT),FilePart(DummyBuffer)))
  2345.                                 {
  2346.                                     case 1:    if(ASCIISetup())
  2347.                                         {
  2348.                                             SendTextFile(DummyBuffer);
  2349.  
  2350.                                             ASCIIShutdown();
  2351.                                         }
  2352.  
  2353.                                         break;
  2354.  
  2355.                                     case 2:    SendTextFile(DummyBuffer);
  2356.  
  2357.                                         break;
  2358.  
  2359.                                     case 0:    break;
  2360.                                 }
  2361.  
  2362.                                 BinaryTransfer = TRUE;
  2363.                             }
  2364.                         }
  2365.                     }
  2366.  
  2367.                     ReleaseWindows();
  2368.                     break;
  2369.  
  2370.             /* Open the phonebook and dial the
  2371.              * list of entries the user will select.
  2372.              */
  2373.  
  2374.         case MEN_PHONEBOOK:    BlockWindows();
  2375.  
  2376.                     while(PhonePanel())
  2377.                     {
  2378.                         if(!DialPanel())
  2379.                         {
  2380.                             Status = OldStatus;
  2381.  
  2382.                             break;
  2383.                         }
  2384.  
  2385.                         Status = OldStatus;
  2386.                     }
  2387.  
  2388.                     ReleaseWindows();
  2389.  
  2390.                     break;
  2391.  
  2392.             /* Dial a single number. */
  2393.  
  2394.         case MEN_DIAL:        BlockWindows();
  2395.  
  2396.                     if(xpr_gets(LocaleString(MSG_TERMMAIN_ENTER_PHONE_NUMBER_TXT),NumberBuffer))
  2397.                     {
  2398.                         if(NumberBuffer[0])
  2399.                         {
  2400.                             struct List *LocalList;
  2401.  
  2402.                             if(LocalList = (struct List *)AllocVec(sizeof(struct List),MEMF_ANY|MEMF_CLEAR))
  2403.                             {
  2404.                                 struct PhoneNode *DialNode;
  2405.  
  2406.                                 NewList(LocalList);
  2407.  
  2408.                                 if(DialNode = (struct PhoneNode *)AllocVec(sizeof(struct PhoneNode),MEMF_ANY|MEMF_CLEAR))
  2409.                                 {
  2410.                                     DialNode -> VanillaNode . ln_Name = (UBYTE *)NumberBuffer;
  2411.  
  2412.                                     AddTail(LocalList,&DialNode -> VanillaNode);
  2413.  
  2414.                                     FreeDialList();
  2415.  
  2416.                                     DialList = LocalList;
  2417.  
  2418.                                     DialPanel();
  2419.  
  2420.                                     Status = OldStatus;
  2421.                                 }
  2422.                                 else
  2423.                                     FreeVec(LocalList);
  2424.                             }
  2425.                         }
  2426.                     }
  2427.  
  2428.                     ReleaseWindows();
  2429.  
  2430.                     break;
  2431.  
  2432.             /* Redial those dial list entries which
  2433.              * we were unable to connect.
  2434.              */
  2435.  
  2436.         case MEN_REDIAL:    BlockWindows();
  2437.  
  2438.                     if(DialList)
  2439.                     {
  2440.                         if(DialList -> lh_Head -> ln_Succ)
  2441.                         {
  2442.                             DialPanel();
  2443.  
  2444.                             Status = OldStatus;
  2445.                         }
  2446.                         else
  2447.                             MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_CURRENT_DIALING_LIST_IS_EMPTY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  2448.                     }
  2449.                     else
  2450.                         MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_CURRENT_DIALING_LIST_IS_EMPTY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  2451.  
  2452.                     ReleaseWindows();
  2453.  
  2454.                     break;
  2455.  
  2456.             /* Play a touch-tone phone number. */
  2457.  
  2458.         case MEN_PLAY:        BlockWindows();
  2459.  
  2460.                     if(xpr_gets(LocaleString(MSG_TERMMAIN_ENTER_PHONE_NUMBER_TO_PLAY_TXT),NumberBuffer))
  2461.                     {
  2462.                         if(!ToneDial(NumberBuffer))
  2463.                             MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(MSG_GLOBAL_FAILED_TO_ALLOCATE_RESOURCES_FOR_PLAYING_TXT));
  2464.                         else
  2465.                             DeleteTone();
  2466.                     }
  2467.  
  2468.                     ReleaseWindows();
  2469.                     break;
  2470.  
  2471.             /* Send a break across the serial line. */
  2472.  
  2473.         case MEN_SENDBREAK:    if(WriteRequest)
  2474.                     {
  2475.                         Status = STATUS_BREAKING;
  2476.  
  2477.                         WriteRequest -> IOSer . io_Command = SDCMD_BREAK;
  2478.  
  2479.                         DoIO(WriteRequest);
  2480.  
  2481.                         Status = OldStatus;
  2482.                     }
  2483.  
  2484.                     break;
  2485.  
  2486.             /* Flush the serial buffers. */
  2487.  
  2488.         case MEN_FLUSHBUFFER:    ClearSerial();
  2489.  
  2490.                     if(ReadRequest)
  2491.                     {
  2492.                         ReadRequest -> IOSer . io_Command    = CMD_READ;
  2493.                         ReadRequest -> IOSer . io_Data        = ReadBuffer;
  2494.                         ReadRequest -> IOSer . io_Length     = 1;
  2495.  
  2496.                         SetSignal(0,SIG_SERIAL);
  2497.  
  2498.                         SendIO(ReadRequest);
  2499.                     }
  2500.  
  2501.                     break;
  2502.  
  2503.             /* Hang up the phone line. */
  2504.  
  2505.         case MEN_HANGUP:    BlockWindows();
  2506.  
  2507.                     Status = STATUS_HANGUP;
  2508.  
  2509.                         /* Are we to drop the DTR line
  2510.                          * before sending the hangup
  2511.                          * string?
  2512.                          */
  2513.  
  2514.                     if(Config . DropDTR)
  2515.                     {
  2516.                         /* Let's be nice and try to transmit the
  2517.                          * `drop the line' command before
  2518.                          * trying to close and reopen the driver.
  2519.                          */
  2520.  
  2521.                         WriteRequest -> IOSer . io_Command    = SIOCMD_SETCTRLLINES;
  2522.                         WriteRequest -> IOSer . io_Offset    = SIOB_DTRF;
  2523.                         WriteRequest -> IOSer . io_Length    = 0;
  2524.  
  2525.                         /* Transmit the command. */
  2526.  
  2527.                         if(!DoIO(WriteRequest))
  2528.                         {
  2529.                             /* Wait a bit... */
  2530.  
  2531.                             WaitTime(1,0);
  2532.  
  2533.                             /* Raise the line again. */
  2534.  
  2535.                             WriteRequest -> IOSer . io_Command    = SIOCMD_SETCTRLLINES;
  2536.                             WriteRequest -> IOSer . io_Offset    = SIOB_DTRF;
  2537.                             WriteRequest -> IOSer . io_Length    = SIOB_DTRF;
  2538.  
  2539.                             DoIO(WriteRequest);
  2540.                         }
  2541.                         else
  2542.                         {
  2543.                             /* Do it the standard way: close and reopen
  2544.                              * the serial driver (the serial.device is
  2545.                              * supposed to drop the DTR line when closed).
  2546.                              */
  2547.  
  2548.                             if(!DropDTR())
  2549.                             {
  2550.                                 if(!MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_REOPEN_UNIT_TXT),LocaleString(MSG_TERMMAIN_IGNORE_QUIT_TXT),Config . SerialDevice,Config . UnitNumber))
  2551.                                     Terminated = TRUE;
  2552.                             }
  2553.                         }
  2554.                     }
  2555.  
  2556.                         /* Transmit the hangup command. */
  2557.  
  2558.                     SerialCommand(Config . ModemHangup);
  2559.  
  2560.                         /* Reset to old status. */
  2561.  
  2562.                     Status = OldStatus;
  2563.  
  2564.                         /* We are no longer online. */
  2565.  
  2566.                     Online = FALSE;
  2567.  
  2568.                         /* Clear the password. */
  2569.  
  2570.                     Password[0] = 0;
  2571.  
  2572.                         /* Clear the user name as well. */
  2573.  
  2574.                     UserName[0] = 0;
  2575.  
  2576.                         /* Note the  last action. */
  2577.  
  2578.                     LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_HANG_UP_TXT));
  2579.  
  2580.                     ReleaseWindows();
  2581.  
  2582.                     break;
  2583.  
  2584.             /* Release the serial device for other
  2585.              * applications.
  2586.              */
  2587.  
  2588.         case MEN_RELEASE:    ReleaseSerial = TRUE;
  2589.                     break;
  2590.  
  2591.             /* Reset the display styles and restore
  2592.              * the colours.
  2593.              */
  2594.  
  2595.         case MEN_RESETSTYLES:    if(XEmulatorBase && Config . Emulation == EMULATION_EXTERNAL)
  2596.                         XEmulatorResetTextStyles(XEM_IO);
  2597.                     else
  2598.                     {
  2599.                         Escape = TRUE;
  2600.  
  2601.                         ConProcess("\033[m",3);
  2602.  
  2603.                         Config . FontScale = SCALE_NORMAL;
  2604.  
  2605.                         switch(Config . ColourMode)
  2606.                         {
  2607.                             case COLOUR_EIGHT:    FgPen = 7;
  2608.                                         break;
  2609.  
  2610.                             case COLOUR_SIXTEEN:    FgPen = 15;
  2611.                                         break;
  2612.  
  2613.                             case COLOUR_AMIGA:
  2614.                             default:        FgPen = 1;
  2615.                                         break;
  2616.                         }
  2617.  
  2618.                         BgPen = 0;
  2619.  
  2620.                         if(RPort -> FgPen != FgPen)
  2621.                             SetAPen(RPort,FgPen);
  2622.  
  2623.                         if(RPort -> BgPen != BgPen)
  2624.                             SetBPen(RPort,BgPen);
  2625.  
  2626.                         SetWrMsk(RPort,0xFF);
  2627.  
  2628.                         Escape = FALSE;
  2629.                     }
  2630.  
  2631.                     break;
  2632.  
  2633.             /* Simply clear the screen and move the
  2634.              * cursor to its home position.
  2635.              */
  2636.  
  2637.         case MEN_CLEARSCREEN:    if(XEmulatorBase && Config . Emulation == EMULATION_EXTERNAL)
  2638.                         XEmulatorClearConsole(XEM_IO);
  2639.                     else
  2640.                     {
  2641.                         Escape = TRUE;
  2642.  
  2643.                         ConProcess("\033[2J\033[H",7);
  2644.  
  2645.                         Escape = FALSE;
  2646.                     }
  2647.  
  2648.                     break;
  2649.  
  2650.             /* Reset the current text rendering font. */
  2651.  
  2652.         case MEN_RESETFONT:    if(XEmulatorBase && Config . Emulation == EMULATION_EXTERNAL)
  2653.                         XEmulatorResetCharset(XEM_IO);
  2654.                     else
  2655.                     {
  2656.                         if(Config . Font == FONT_IBM && IBM)
  2657.                             CurrentFont = IBM;
  2658.                         else
  2659.                             CurrentFont = Topaz;
  2660.  
  2661.                         SetFont(RPort,CurrentFont);
  2662.                     }
  2663.  
  2664.                     break;
  2665.  
  2666.             /* Reset the whole terminal. */
  2667.  
  2668.         case MEN_RESETTERMINAL:    if(XEmulatorBase && Config . Emulation == EMULATION_EXTERNAL)
  2669.                         XEmulatorResetConsole(XEM_IO);
  2670.                     else
  2671.                     {
  2672.                         DoCancel();
  2673.  
  2674.                         Escape = TRUE;
  2675.  
  2676.                         ConProcess("\033c",2);
  2677.  
  2678.                         Escape = FALSE;
  2679.                     }
  2680.  
  2681.                     break;
  2682.  
  2683.             /* Save screen as IFF-ILBM file. */
  2684.  
  2685.         case MEN_SAVEILBM:    BlockWindows();
  2686.  
  2687.                     if(FileRequest = GetFile(LocaleString(MSG_TERMMAIN_SAVE_SCREEN_IFF_TXT),"","",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT)))
  2688.                     {
  2689.                         if(!SaveRPort(&Screen -> RastPort,VPort,0,Window -> TopEdge,Window -> Width,Window -> Height,Screen -> Width,Screen -> Height,FALSE,DummyBuffer))
  2690.                             MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_SAVE_SCREEN_TO_FILE_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),DummyBuffer);
  2691.  
  2692.                         FreeAslRequest(FileRequest);
  2693.                     }
  2694.  
  2695.                     ReleaseWindows();
  2696.  
  2697.                     break;
  2698.  
  2699.             /* Save screen as ASCII file. */
  2700.  
  2701.         case MEN_SAVEASCII:    BlockWindows();
  2702.  
  2703.                     if(FileRequest = GetFile(LocaleString(MSG_TERMMAIN_SAVE_SCREEN_ASCII_TXT),"","",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT)))
  2704.                     {
  2705.                         if(GetFileSize(DummyBuffer))
  2706.                         {
  2707.                             switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
  2708.                             {
  2709.                                 case 1:    SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  2710.                                     break;
  2711.  
  2712.                                 case 2:    if(SomeFile = Open(DummyBuffer,MODE_READWRITE))
  2713.                                     {
  2714.                                         if(Seek(SomeFile,0,OFFSET_END) == -1)
  2715.                                         {
  2716.                                             Close(SomeFile);
  2717.  
  2718.                                             SomeFile = NULL;
  2719.                                         }
  2720.                                     }
  2721.  
  2722.                                     break;
  2723.  
  2724.                                 case 0:    SomeFile = ~0;
  2725.                                     break;
  2726.                             }
  2727.                         }
  2728.                         else
  2729.                             SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  2730.  
  2731.                         if(!SomeFile)
  2732.                             MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_SAVE_SCREEN_TO_FILE_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),DummyBuffer);
  2733.                         else
  2734.                         {
  2735.                             if(SomeFile != ~0)
  2736.                             {
  2737.                                 WORD     i,j;
  2738.                                 UBYTE    *Buffer;
  2739.  
  2740.                                 for(i = 0 ; i < RasterHeight ; i++)
  2741.                                 {
  2742.                                     Buffer = &Raster[i * RasterWidth];
  2743.  
  2744.                                     j = LastColumn;
  2745.  
  2746.                                     while(j >= 0 && Buffer[j] == ' ')
  2747.                                         j--;
  2748.  
  2749.                                     if(j >= 0)
  2750.                                     {
  2751.                                         if(!FWrite(SomeFile,Buffer,j + 1,1))
  2752.                                             break;
  2753.                                     }
  2754.  
  2755.                                     if(!FWrite(SomeFile,"\n",1,1))
  2756.                                         break;
  2757.                                 }
  2758.  
  2759.                                 Close(SomeFile);
  2760.  
  2761.                                 SetProtection(DummyBuffer,FIBF_EXECUTE);
  2762.                             }
  2763.                         }
  2764.  
  2765.                         FreeAslRequest(FileRequest);
  2766.                     }
  2767.  
  2768.                     ReleaseWindows();
  2769.  
  2770.                     break;
  2771.  
  2772.             /* Set the serial preferences. */
  2773.  
  2774.         case MEN_SERIAL:    BlockWindows();
  2775.  
  2776.                     if(SerialPanel(&Config))
  2777.                         ConfigSetup();
  2778.  
  2779.                     ReleaseWindows();
  2780.  
  2781.                     break;
  2782.  
  2783.             /* Set the modem preferences. */
  2784.  
  2785.         case MEN_MODEM:        BlockWindows();
  2786.  
  2787.                     if(ModemPanel(&Config))
  2788.                         FlowInit();
  2789.  
  2790.                     ReleaseWindows();
  2791.  
  2792.                     break;
  2793.  
  2794.             /* Set the fast macros. */
  2795.  
  2796.         case MEN_FASTMACROS:    BlockWindows();
  2797.  
  2798.                     FastMacroPanel();
  2799.  
  2800.                     ReleaseWindows();
  2801.  
  2802.                     break;
  2803.  
  2804.             /* Set the keyboard macros. */
  2805.  
  2806.         case MEN_MACROS:    BlockWindows();
  2807.  
  2808.                     if(XEmulatorBase && Config . Emulation == EMULATION_EXTERNAL)
  2809.                     {
  2810.                         XEmulatorMacroKeyFilter(XEM_IO,NULL);
  2811.  
  2812.                         MacroPanel(MacroKeys);
  2813.  
  2814.                         SetupXEM_MacroKeys(MacroKeys);
  2815.                     }
  2816.                     else
  2817.                         MacroPanel(MacroKeys);
  2818.  
  2819.                     ReleaseWindows();
  2820.  
  2821.                     break;
  2822.  
  2823.             /* Set the screen preferences. */
  2824.  
  2825.         case MEN_SCREEN:    BlockWindows();
  2826.  
  2827.                     if(ScreenPanel(&Config))
  2828.                         ResetDisplay = TRUE;
  2829.                     else
  2830.                         PubScreenStuff();
  2831.  
  2832.                     if(memcmp(&PrivateConfig . Colours[0],&Config . Colours[0],sizeof(UWORD) * 16))
  2833.                     {
  2834.                         switch(Config . ColourMode)
  2835.                         {
  2836.                             case COLOUR_EIGHT:    CopyMem(&Config . Colours[0],&ANSIColours[0],16 * sizeof(UWORD));
  2837.                                         break;
  2838.  
  2839.                             case COLOUR_SIXTEEN:    CopyMem(&Config . Colours[0],&EGAColours[0],16 * sizeof(UWORD));
  2840.                                         break;
  2841.  
  2842.                             case COLOUR_AMIGA:    CopyMem(&Config . Colours[0],&DefaultColours[0],16 * sizeof(UWORD));
  2843.                                         break;
  2844.  
  2845.                             case COLOUR_MONO:    CopyMem(&Config . Colours[0],&AtomicColours[0],16 * sizeof(UWORD));
  2846.                                         break;
  2847.                         }
  2848.                     }
  2849.  
  2850.                     ReleaseWindows();
  2851.  
  2852.                     break;
  2853.  
  2854.             /* Set the terminal preferences. */
  2855.  
  2856.         case MEN_TERMINAL:    BlockWindows();
  2857.  
  2858.                     TerminalPanel(&Config);
  2859.  
  2860.                     ConfigSetup();
  2861.  
  2862.                     ReleaseWindows();
  2863.  
  2864.                     break;
  2865.  
  2866.         case MEN_COMMANDS:    BlockWindows();
  2867.  
  2868.                     CommandPanel(&Config);
  2869.  
  2870.                     ReleaseWindows();
  2871.  
  2872.                     break;
  2873.  
  2874.         case MEN_EMULATION:    BlockWindows();
  2875.  
  2876.                     if(XEmulatorBase && Config . Emulation == EMULATION_EXTERNAL)
  2877.                     {
  2878.                         OptionTitle = LocaleString(MSG_TERMMAIN_EMULATION_PREFERENCES_TXT);
  2879.  
  2880.                         XEmulatorOptions(XEM_IO);
  2881.  
  2882.                         OptionTitle = NULL;
  2883.                     }
  2884.                     else
  2885.                         EmulationPanel(&Config);
  2886.  
  2887.                     ReleaseWindows();
  2888.  
  2889.                     break;
  2890.  
  2891.         case MEN_MISC:        BlockWindows();
  2892.  
  2893.                     MiscPanel(&Config);
  2894.  
  2895.                     ConfigSetup();
  2896.  
  2897.                     ReleaseWindows();
  2898.  
  2899.                     break;
  2900.  
  2901.         case MEN_PATH:        BlockWindows();
  2902.  
  2903.                     if(PathPanel(&Config))
  2904.                     {
  2905.                         DeleteBeep();
  2906.  
  2907.                         if(!OpenSound(Config . BeepSound))
  2908.                             MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_SOUND_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Config . BeepSound);
  2909.  
  2910.                         CreateBeep();
  2911.                     }
  2912.  
  2913.                     ReleaseWindows();
  2914.  
  2915.                     break;
  2916.  
  2917.         case MEN_HOTKEYS:    BlockWindows();
  2918.  
  2919.                     if(HotkeyPanel(&Hotkeys))
  2920.                     {
  2921.                         if(!SetupCx())
  2922.                             MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_SET_UP_HOTKEYS_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  2923.                     }
  2924.  
  2925.                     ReleaseWindows();
  2926.  
  2927.                     break;
  2928.  
  2929.         case MEN_SPEECH:    BlockWindows();
  2930.  
  2931.                     SpeechPanel();
  2932.  
  2933.                     ReleaseWindows();
  2934.  
  2935.                     break;
  2936.  
  2937.             /* Ignore the rest. */
  2938.  
  2939.         default:        break;
  2940.     }
  2941. }
  2942.  
  2943.     /* HandleMenu(ULONG Code,ULONG Qualifier):
  2944.      *
  2945.      *    Skip along the number of selected menu items and
  2946.      *    handle the associated functions.
  2947.      */
  2948.  
  2949. VOID
  2950. HandleMenu(ULONG Code,ULONG Qualifier)
  2951. {
  2952.     struct MenuItem *MenuItem;
  2953.  
  2954.         /* Check until the last menuitem has been
  2955.          * processed.
  2956.          */
  2957.  
  2958.     while(Code != MENUNULL)
  2959.     {
  2960.             /* Pick up the associated menu item. */
  2961.  
  2962.         if(MenuItem = ItemAddress(Menu,Code))
  2963.         {
  2964.             HandleCode((ULONG)GTMENUITEM_USERDATA(MenuItem),Qualifier,MenuItem);
  2965.  
  2966.             Code = MenuItem -> NextSelect;
  2967.         }
  2968.         else
  2969.             break;
  2970.     }
  2971. }
  2972.